home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gnulib / libsrc98.zoo / crt0.c < prev    next >
C/C++ Source or Header  |  1993-12-01  |  14KB  |  480 lines

  1. /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2.  * NB: This file is used for both 16 and 32 bit code.
  3.  * USE NO "int"s IN HERE!!!!
  4.  *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  5.  *
  6.  *
  7.  * Crt0: C run-time initialization code.
  8.  * Written by Eric R. Smith, and placed in the public domain.
  9.  * Use at your own risk.
  10.  *
  11.  * _start(base): sets things up for the process whose basepage is
  12.  *    base. In particular, it sets up a valid environment, shrinks the
  13.  *    TPA to a reasonable value, and parses the command line.
  14.  *
  15.  * 01/03/89 ++jrb
  16.  *    The (new) meaning of _stksize: (thanks to allan pratt for the feedback)
  17.  *
  18.  * 11/27/91 ++jrb
  19.  *     More meanings for _stksize (thanks to eric and allan for the feedback)
  20.  *
  21.  *    _stksize            meaning
  22.  *      -4L        keep 3/4, free 1/4, malloc from own heap
  23.  *      -3L        keep 2/4 (1/2), free 1/2 malloc from own heap
  24.  *      -2L        keep 1/4 of memory, free 3/4, malloc from own heap
  25.  *
  26.  *    NOTE: all of the following will do malloc from Malloc() first.
  27.  *    when that fails, in the -1L case malloc() will then do further
  28.  *    mallocs from our own heap. This lets us use the maximum amount of
  29.  *      memory in traditional ST's as well as in newer split address
  30.  *    STs. In the >=0 cases futher malloc()'s will fail, and they
  31.  *    will not try to malloc() from own heap. Out own space in the >= 0
  32.  *    cases are intended mainly for stack+alloca()'s.
  33.  *
  34.  *      -1L        keep all of memory (except MINFREE at top) and do
  35.  *            mallocs from own heap, with heap grown upwards towards
  36.  *            stack, and the stack growing down towards heap,
  37.  *            with a minimum slush between them so that they
  38.  *            dont meet (only checked while malloc'ing). With
  39.  *            this model, further spawning is not possible, but it is
  40.  *            well suited for programs such as gcc-cc1 etc.
  41.  *            Thanks to Piet van Oostrum & Atze Dijkstra for this idea
  42.  *
  43.  *    0L        keep minimum amount of memory. this is also the
  44.  *            case when _stksize is undefined by the user.
  45.  *    1L        keep 1/4 of memory, free 3/4 ( as in Alcyon GEMSTART)
  46.  *    2L        keep 2/4 (1/2), free rest
  47.  *    3L        keep 3/4, free 1/4
  48.  *    other        keep that many bytes
  49.  *    -other        keep |other| bytes and malloc from own heap
  50.  *
  51.  * 02/14/90 ++jrb (thanks edgar)
  52.  *    auto acc detect
  53.  *    undump friendly
  54.  *   Note: some of the stuff here may seem extraneous: these are in
  55.  *     prep for upcoming plug'n play device interface
  56.  *     (the moment the ol'boss lets me do some "real" work).
  57.  *
  58.  *
  59.  * NOTE: dumping applications should use _initial_stack instead: if
  60.  *     !=0, then _stksize is initialized from _initial_stack, and
  61.  *     mallocs are always from internal heap. (TeX works much better now),
  62.  *     thanks edgar!
  63.  *
  64.  * Acc convention:
  65.  *    user sets _heapbase to bottom of stack + heap area
  66.  *         sets _stksize to the size of this area
  67.  *         at startup, sp will be set to top of this area
  68.  *         (_heapbase  + _stksize ) and malloc()'s will happen from heap.
  69.  *        (note malloc() and *not* Malloc())
  70.  *     OR
  71.  *    user sets only _stksize. then _heapbase is set to Malloc(_stksize)
  72.  *    sp to _heapbase + _stksize and mallocs all happen from this heap.
  73.  *
  74.  * 02/16/90 ++jrb
  75.  *  - bug fix: dont get screwed by desktop launch when fast bit is set
  76.  *             convert env string to format usable
  77.  *        (atari get your act together!!)
  78.  */
  79.  
  80. #include <basepage.h>
  81. #include <osbind.h>
  82. #ifndef _COMPILER_H
  83. #include <compiler.h>
  84. #endif
  85. #include <stddef.h>
  86.  
  87. #define isspace(c) ((c) == ' '||(c) == '\t')
  88. #define BUFSIZ    ((unsigned long)1024)    /* this must track the value */
  89.                     /* in stdio.h                */
  90. #define MINFREE    (8L * 1024L)        /* free atleast this much mem */
  91.                     /* on top */
  92. #define MINKEEP (8L * 1024L)        /* keep atleast this much mem */
  93.  
  94. /*
  95.  * this little goodie is for emacs
  96.  * edgar: note: it has grown two leading '_',
  97.  *              adjust in emacs/src/sysdep.c:start_of_data()
  98.  *
  99.  * __data_start removed, as that can be determined from the basepage.
  100.  */
  101.  
  102. BASEPAGE *_base;
  103. char **environ;
  104. static long argc;
  105. static char **argv;
  106.  
  107. /*
  108.  * initial stack is used primarily by dumping application,
  109.  * if it is, malloc is always from heap, and _stksize is init
  110.  * from initial_stack (to preserve the value in the undumped run)
  111.  */
  112. long _initial_stack;            /* .comm __initial_size, 4 */
  113. extern long _stksize;            /* picked up from user or stksiz.c */
  114. /* set to heap base addr when (_stksize <= -1L) || _initial_stack || When DA */
  115. void *_heapbase;
  116.  
  117. /* default sizeof stdio buffers */
  118. size_t __DEFAULT_BUFSIZ__;    /* .comm             */
  119.  
  120. /* are we an app? */
  121. short _app;
  122.  
  123. /* are we on a split addr mem ST */
  124. short _split_mem = 0;
  125.  
  126. /* externs to pull in ident strings of all used libraries into the
  127.    executable. if a library is not used, then the extern is satisfied
  128.    by a dummy in the library
  129.  */
  130. asm("
  131.     .globl ___Ident_libg
  132.     .globl ___Ident_curses
  133.     .globl ___Ident_widget
  134.     .globl ___Ident_gem
  135.     .globl ___Ident_pml
  136.     .globl ___Ident_gnulib
  137.      ");
  138.  
  139. static void _acc_main __PROTO((void));
  140. static void _start1 __PROTO((BASEPAGE *bp));
  141. static long parseargs __PROTO((BASEPAGE *bp));
  142. static void setup_handlers __PROTO((void));
  143. static void _start0 __PROTO((BASEPAGE *));
  144. static void setup_handlers __PROTO((void));
  145. __EXTERN void _main __PROTO((long, char **, char **));
  146. __EXTERN void _init_signal __PROTO((void));
  147. __EXTERN void _start __PROTO((BASEPAGE *));
  148. #ifdef __GCRT0__
  149. __EXTERN void monstartup __PROTO((void *lowpc, void *highpc));
  150. __EXTERN void monitor __PROTO((void *lowpc, void *highpc, void *buffer, unsigned long bufsize, unsigned int nfunc));
  151. __EXTERN void moncontrol __PROTO((long flag));
  152. __EXTERN void _mcleanup __PROTO((void));
  153. __EXTERN int profil __PROTO((void *buff, unsigned long bufsiz, unsigned long offset, int shift));
  154. #endif
  155.  
  156. /*
  157.  * From: kbad@atari.UUCP (Ken Badertscher)
  158.  * Newsgroups: comp.sys.atari.st
  159.  * Subject: Am I a DA? (long)
  160.  *   .....
  161.  * I mentioned before that a DA's registers are garbage on startup, well,
  162.  * that's not entirely true.  When the DA gets control, register A0 always
  163.  * points to its basepage.  When a program is started by a GEMDOS Pexec(),
  164.  * register A0 is always cleared.  Using this fact, it is possible to
  165.  * implement startup code which gets the basepage address from register A0
  166.  * if the code is launched as a DA, or at 4(sp) if the code is launched by
  167.  * Pexec().  Since it knows how it was launched, it can also do the stack
  168.  * setup required of a DA, otherwise it can use the stack pointer it gets.
  169.  *
  170.  */
  171. /*
  172.  * revert back to testing A0 (instead of SP) after controversy on the net.
  173.  * packers will just have to fix themselves.
  174.  * in addition to testing A0 check long A0@(36) (parents basepage). for an
  175.  * acc this should be NULL.
  176.  */
  177. __asm__("
  178.      .text                
  179.      .even                
  180.      .globl __start            
  181. __start:
  182. "
  183. #ifdef __MBASE__
  184. "    movl    a0,a1            /* Find basepage, data seg */
  185.     cmpw    #0,a1
  186.     jne    1f
  187.     movl    sp@(4),a1
  188. 1:
  189.     movl    a1@(16)," __MBASESTR__ "    /* Set base to data seg + 32K */
  190.     subw    #32768," __MBASESTR__ "
  191.  
  192. "
  193. #define    Base    __MBASESTR__ "@(__base)"
  194. #define Heapbase __MBASESTR__ "@(__heapbase)"
  195. #define Stksize    __MBASESTR__ "@(__stksize)"
  196. #else
  197. #define Base    "__base"
  198. #define Heapbase "__heapbase"
  199. #define Stksize "__stksize"
  200. #endif
  201. "    cmpw    #0,a0             /* test acc or prog  */
  202.      jeq    __start0         /* br if prog          */
  203.     tstl    a0@(36)             /* tst parent basepage pointer */
  204.     jne     __start0         /* its a prog if != 0  */
  205.  
  206.  /* its an acc, set up a stck+heap */
  207.     movl    a0," Base "         /* sto basepage    */
  208.     tstl    " Heapbase "         /* setup _heapbase and sp */
  209.     jne    1f
  210.     movl    " Stksize ",d3         /* _heapbase not specified */
  211.     addql    #3, d3
  212.     andl    #0xfffffffc,d3
  213.     movl    d3,sp@-             /* _heapbase = Malloc(_stksize) */
  214.         movw    #0x48,sp@-
  215.     trap    #1
  216.     addqw    #6,sp
  217.     movl    d0," Heapbase "
  218.     addl    d3,d0
  219.     movl    d0, sp              /* sp = _heapbase + _stksize */
  220.     jra    __acc_main
  221. 1:                     /* heap base specified */
  222.      movl    " Heapbase ",sp         /* setup sp        */
  223.      addl    " Stksize ",sp        
  224.      jra    __acc_main
  225.     .data");               /* acc main          */
  226.                        /* dont even think of */
  227.                        /* dropping through    */
  228.  
  229. static char    *acc_argv[] = {"", (char *) 0}; /* no name and no arguments */
  230.  
  231. static void _acc_main(void)
  232. {
  233.     _app = 0;                /* this is an accessory */
  234.     _main(1L, acc_argv, acc_argv);
  235.     /*NOTREACHED*/
  236. }
  237.  
  238. void _sta